﻿using Certify.Client;
using Certify.Config;
using Certify.Management;
using Certify.Models;
using Certify.Models.Config;
using Certify.Models.Config.Migration;
using Certify.Models.Hub;
using Certify.Models.Providers;
using Certify.Models.Reporting;
using Certify.Models.Utils;
using Certify.Shared;
using Microsoft.AspNetCore.DataProtection;
using ServiceControllers = Certify.Service.Controllers;

namespace Certify.Server.HubService.Services
{
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
    /// <summary>
    /// The HubService is a surrogate for the Certify Server Core Service, Service API and Client. The Hub hosts a Certify Server Core instead of talking to a Service instance over http, skipping a layer of abstraction and a communication layer.
    /// A further layer of abstraction can be skipped by implementing all controller logic in Certify.Core and using that directly
    /// </summary>
    public class CertifyDirectHubService : ICertifyInternalApiClient
    {
        private ICertifyManager _certifyManager;
        private IDataProtectionProvider _dataProtectionProvider;

        /// <summary>
        /// Initializes a new instance of the CertifyHubService class.
        /// </summary>
        /// <param name="certifyManager">Used to manage certification processes within the service.</param>
        /// <param name="dataProtectionProvider">Provides data protection functionalities for secure data handling.</param>
        public CertifyDirectHubService(ICertifyManager certifyManager, IDataProtectionProvider dataProtectionProvider)
        {
            _certifyManager = certifyManager;
            _dataProtectionProvider = dataProtectionProvider;
        }

        private ServiceControllers.AccessController _accessController(AuthContext authContext)
        {
            var controller = new ServiceControllers.AccessController(_certifyManager, _dataProtectionProvider);
            controller.SetCurrentAuthContext(authContext);
            return controller;
        }

        private ServiceControllers.ManagedChallengeController _managedChallengeController(AuthContext authContext)
        {
            var controller = new ServiceControllers.ManagedChallengeController(_certifyManager);
            controller.SetCurrentAuthContext(authContext);
            return controller;
        }

        private ServiceControllers.ManagedInstanceController _managedInstanceController(AuthContext authContext)
        {
            var controller = new ServiceControllers.ManagedInstanceController(_certifyManager);
            controller.SetCurrentAuthContext(authContext);
            return controller;
        }

        private ServiceControllers.SystemController _systemController(AuthContext authContext)
        {
            var controller = new ServiceControllers.SystemController(_certifyManager);
            controller.SetCurrentAuthContext(authContext);
            return controller;
        }

        private ServiceControllers.TagController _tagController(AuthContext authContext)
        {
            var controller = new ServiceControllers.TagController(_certifyManager);
            controller.SetCurrentAuthContext(authContext);
            return controller;
        }

        private ServiceControllers.ManagedLicenseController _licenseController(AuthContext authContext)
        {
            var controller = new ServiceControllers.ManagedLicenseController(_certifyManager);
            controller.SetCurrentAuthContext(authContext);
            return controller;
        }

        private ServiceControllers.OidcProviderController __oidcProviderController(AuthContext authContext)
        {
            var controller = new ServiceControllers.OidcProviderController(_certifyManager);
            controller.SetCurrentAuthContext(authContext);
            return controller;
        }

        public Task<Preferences> GetPreferences(AuthContext? authContext = null) => Task.FromResult(new ServiceControllers.PreferencesController(_certifyManager).GetPreferences());

        public Task<ActionResult> AddSecurityPrincipal(SecurityPrincipal principal, AuthContext authContext) => _accessController(authContext).AddSecurityPrincipal(principal);
        /// <summary>
        /// Checks if the security principal has access to the specified resource.
        /// </summary>
        /// <param name="check">The access check details.</param>
        /// <param name="authContext">The authentication context.</param>
        /// <returns>A task that represents the asynchronous operation. The task result contains a boolean indicating whether the security principal has access.</returns>
        public Task<bool> CheckSecurityPrincipalHasAccess(AccessCheck check, AuthContext authContext) => _accessController(authContext).CheckSecurityPrincipalHasAccess(check);
        public Task<ICollection<AssignedRole>> GetSecurityPrincipalAssignedRoles(string id, AuthContext authContext) => _accessController(authContext).GetSecurityPrincipalAssignedRoles(id);
        public Task<RoleStatus> GetSecurityPrincipalRoleStatus(string id, AuthContext authContext) => _accessController(authContext).GetSecurityPrincipalRoleStatus(id);
        public Task<ICollection<SecurityPrincipal>> GetSecurityPrincipals(AuthContext authContext) => _accessController(authContext).GetSecurityPrincipals();
        public Task<ActionResult> AddAssignedAccessToken(AssignedAccessToken token, AuthContext authContext) => _accessController(authContext).AddAssignedccessToken(token);
        public Task<ActionResult> RemoveAssignedAccessToken(string id, AuthContext authContext) => _accessController(authContext).RemoveAssignedAccessToken(id);
        public Task<ActionResult> CheckApiTokenHasAccess(AccessToken token, AccessCheck check, AuthContext authContext) => _accessController(authContext).CheckApiTokenHasAccess(new AccessTokenCheck { Check = check, Token = token });
        public Task<ICollection<AssignedAccessToken>> GetAssignedAccessTokens(AuthContext authContext) => _accessController(authContext).GetAssignedAccessTokens();
        public Task<ActionResult> RemoveSecurityPrincipal(string id, AuthContext authContext) => _accessController(authContext).DeleteSecurityPrincipal(id);
        public Task<ActionResult> UpdateSecurityPrincipal(SecurityPrincipal principal, AuthContext authContext) => _accessController(authContext).UpdateSecurityPrincipal(principal);
        public Task<ActionResult> UpdateSecurityPrincipalAssignedRoles(SecurityPrincipalAssignedRoleUpdate update, AuthContext authContext) => _accessController(authContext).UpdateSecurityPrincipalAssignedRoles(update);
        public Task<ActionResult> UpdateSecurityPrincipalPassword(SecurityPrincipalPasswordUpdate passwordUpdate, AuthContext authContext) => _accessController(authContext).UpdatePassword(passwordUpdate);
        public Task<SecurityPrincipalCheckResponse> ValidateSecurityPrincipalPassword(SecurityPrincipalPasswordCheck passwordCheck, AuthContext authContext) => _accessController(authContext).Validate(passwordCheck);
        public Task<ICollection<Role>> GetAccessRoles(AuthContext authContext) => _accessController(authContext).GetRoles();

        public Task<ICollection<ManagedChallenge>> GetManagedChallenges(AuthContext authContext) => _managedChallengeController(authContext).Get();
        public Task<ActionResult> UpdateManagedChallenge(ManagedChallenge update, AuthContext authContext) => _managedChallengeController(authContext).Update(update);
        public Task<ActionResult> CleanupManagedChallenge(ManagedChallengeRequest request, AuthContext authContext) => _managedChallengeController(authContext).CleanupChallengeResponse(request);
        public Task<ActionResult> RemoveManagedChallenge(string id, AuthContext authContext) => _managedChallengeController(authContext).Delete(id);
        public Task<ActionResult> PerformManagedChallenge(ManagedChallengeRequest request, AuthContext authContext) => _managedChallengeController(authContext).PerformChallengeResponse(request);

        public Task<ManagedInstanceInfo> GetHubManagedInstance(string id, AuthContext authContext) => _managedInstanceController(authContext).Get(id);
        public Task<ActionResult<ManagedInstanceInfo>> AddHubManagedInstance(ManagedInstanceInfo item, AuthContext authContext) => _managedInstanceController(authContext).Add(item);
        public Task<ActionResult> UpdateHubManagedInstance(ManagedInstanceInfo item, AuthContext authContext) => _managedInstanceController(authContext).Update(item);
        public Task<ICollection<ManagedInstanceInfo>> GetHubManagedInstances(AuthContext authContext) => _managedInstanceController(authContext).List();
        public Task<ActionResult> RemoveHubManagedInstance(string id, AuthContext authContext) => _managedInstanceController(authContext).Remove(id);
        public Task<HubInfo> GetHubInfo(AuthContext authContext) => _systemController(authContext).GetHubInfo();

        public Task<ActionResult> AddAccount(ContactRegistration contact, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<CertificateRequestResult>> BeginAutoRenewal(RenewalSettings settings, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<CertificateRequestResult> BeginCertificateRequest(string managedItemId, bool resumePaused, bool isInteractive, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ActionResult> ChangeAccountKey(string storageKey, string? newKeyPEM = null, AuthContext? authContext = null) => throw new NotImplementedException();

        public Task<UpdateCheck> CheckForUpdates(AuthContext? authContext = null) => throw new NotImplementedException();

        public Task<List<ActionStep>> CopyDataStore(string sourceId, string targetId, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ActionResult> DeleteCertificateAuthority(string id, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ActionResult> DeleteCredential(string credentialKey, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<bool> DeleteManagedCertificate(string managedItemId, AuthContext? authContext = null) => throw new NotImplementedException();

        public Task<List<AccountDetails>> GetAccounts(AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<string> GetAppVersion(AuthContext? authContext = null) => Task.FromResult(new ServiceControllers.SystemController(_certifyManager).GetAppVersion());

        public Task<List<CertificateAuthority>> GetCertificateAuthorities(AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<ChallengeProviderDefinition>> GetChallengeAPIList(AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<StoredCredential>> GetCredentials(AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<SimpleAuthorizationChallengeItem>> GetCurrentChallenges(string type, string key, AuthContext? authContext = null) => new ServiceControllers.ManagedCertificatesController(_certifyManager).GetCurrentChallenges(type, key);

        public Task<List<DataStoreConnection>> GetDataStoreConnections(AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<ProviderDefinition>> GetDataStoreProviders(AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<DeploymentProviderDefinition> GetDeploymentProviderDefinition(string id, DeploymentTaskConfig config, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<DeploymentProviderDefinition>> GetDeploymentProviderList(AuthContext? authContext = null) => throw new NotImplementedException();

        public Task<LogItem[]> GetItemLog(string id, int limit, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ManagedCertificate> GetManagedCertificate(string managedItemId, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<ManagedCertificate>> GetManagedCertificates(ManagedCertificateFilter filter, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ManagedCertificateSearchResult> GetManagedCertificateSearchResult(ManagedCertificateFilter filter, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<StatusSummary> GetManagedCertificateSummary(ManagedCertificateFilter filter, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<DomainOption>> GetServerSiteDomains(StandardServerTypes serverType, string serverSiteId, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<SiteInfo>> GetServerSiteList(StandardServerTypes serverType, string? itemId = null, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<Version> GetServerVersion(StandardServerTypes serverType, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<bool> IsServerAvailable(StandardServerTypes serverType, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<StatusMessage>> PerformChallengeCleanup(ManagedCertificate site, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<ActionStep>> PerformDeployment(string managedCertificateId, string taskId, bool isPreviewOnly, bool forceTaskExecute, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ImportExportPackage> PerformExport(ExportRequest exportRequest, AuthContext authContext) => throw new NotImplementedException();
        public Task<ICollection<ActionStep>> PerformImport(ImportRequest importRequest, AuthContext authContext) => throw new NotImplementedException();
        public Task<List<ActionResult>> PerformManagedCertMaintenance(string? id = null, AuthContext? authContext = null) => throw new NotImplementedException();

        public Task<List<ActionResult>> PerformServiceDiagnostics(AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<ActionStep>> PreviewActions(ManagedCertificate site, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<CertificateRequestResult> ReapplyCertificateBindings(string managedItemId, bool isPreviewOnly, bool includeDeploymentTasks, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<CertificateRequestResult>> RedeployManagedCertificates(bool isPreviewOnly, bool includeDeploymentTasks, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<CertificateRequestResult> RefetchCertificate(string managedItemId, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ActionResult> RemoveAccount(string storageKey, bool deactivate, AuthContext? authContext = null) => throw new NotImplementedException();

        public Task<StatusMessage> RevokeManageSiteCertificate(string managedItemId, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<ActionStep>> RunConfigurationDiagnostics(StandardServerTypes serverType, string serverSiteId, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<ActionStep>> SetDefaultDataStore(string dataStoreId, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<bool> SetPreferences(Preferences preferences, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<StatusMessage>> TestChallengeConfiguration(ManagedCertificate site, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ActionResult> TestCredentials(string credentialKey, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<ActionStep>> TestDataStoreConnection(DataStoreConnection dataStoreConnection, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ActionResult> UpdateAccountContact(ContactRegistration contact, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ActionResult> UpdateCertificateAuthority(CertificateAuthority ca, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<StoredCredential> UpdateCredentials(StoredCredential credential, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<ActionStep>> UpdateDataStoreConnection(DataStoreConnection dataStoreConnection, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ManagedCertificate> UpdateManagedCertificate(ManagedCertificate site, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<List<ActionResult>> ValidateDeploymentTask(DeploymentTaskValidationInfo info, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ActionResult> JoinManagementHub(HubJoiningClientSecret hubJoiningClientSecret, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ActionResult> CheckManagementHubCredentials(HubJoiningClientSecret hubJoiningClientSecret, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ActionResult> CheckManagementHubConnectionStatus(AuthContext? authContext = null) => throw new NotImplementedException();

        public Task<ActionResult> AddHubItemTag(ItemTag tag, AuthContext authContext) => _tagController(authContext).AddTag(tag);
        public Task<ICollection<ItemTag>> GetHubItemTags(AuthContext authContext) => _tagController(authContext).GetTags();
        public Task<DnsZoneQueryResult> GetDnsProviderZones(string providerTypeId, string credentialId, AuthContext? authContext = null) => throw new NotImplementedException();
        public Task<ManagedCertificate> ResetManagedCertificateStatus(string managedItemId, AuthContext authContext = null) => throw new NotImplementedException();

        public Task<ActionResult> RemoveManagedLicense(string id, AuthContext authContext) => _licenseController(authContext).RemoveManagedLicense(id);
        public Task<ICollection<ManagedLicense>> GetManagedLicenses(AuthContext authContext) => _licenseController(authContext).GetManagedLicenses();
        public Task<ActionResult> AddManagedLicense(ManagedLicense item, AuthContext authContext) => _licenseController(authContext).AddManagedLicense(item);
        public Task<ActionResult> UpdateManagedLicense(ManagedLicense item, AuthContext authContext) => _licenseController(authContext).UpdateManagedLicense(item);

        public Task<ActionResult> RemoveOidcProvider(string id, AuthContext authContext) => __oidcProviderController(authContext).RemovOidcProvider(id);
        public Task<ICollection<OidcProviderConfig>> GetOidcProviders(AuthContext authContext) => __oidcProviderController(authContext).GetOidcProviders();
        public Task<ActionResult> AddOidcProvider(OidcProviderConfig item, AuthContext authContext) => __oidcProviderController(authContext).AddOidcProvider(item);
        public Task<ActionResult> UpdateOidcProvider(OidcProviderConfig item, AuthContext authContext) => __oidcProviderController(authContext).UpdateOidcProvider(item);
        public Task<OidcProviderConfig> GetOidcProviderWithSecret(string id, AuthContext authContext) => __oidcProviderController(authContext).GetOidcProvidersWithSecret(id);

#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
    }
}
